home *** CD-ROM | disk | FTP | other *** search
/ Enter 2006 September / Enter 09 2006.iso / Internet / SpamExperts Home 1.1 / SpamExperts Home.exe / lib / spamexperts.modules / random.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-07-14  |  23.3 KB  |  772 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. '''Random variable generators.
  5.  
  6.     integers
  7.     --------
  8.            uniform within range
  9.  
  10.     sequences
  11.     ---------
  12.            pick random element
  13.            pick random sample
  14.            generate random permutation
  15.  
  16.     distributions on the real line:
  17.     ------------------------------
  18.            uniform
  19.            normal (Gaussian)
  20.            lognormal
  21.            negative exponential
  22.            gamma
  23.            beta
  24.            pareto
  25.            Weibull
  26.  
  27.     distributions on the circle (angles 0 to 2pi)
  28.     ---------------------------------------------
  29.            circular uniform
  30.            von Mises
  31.  
  32. General notes on the underlying Mersenne Twister core generator:
  33.  
  34. * The period is 2**19937-1.
  35. * It is one of the most extensively tested generators in existence
  36. * Without a direct way to compute N steps forward, the
  37.   semantics of jumpahead(n) are weakened to simply jump
  38.   to another distant state and rely on the large period
  39.   to avoid overlapping sequences.
  40. * The random() method is implemented in C, executes in
  41.   a single Python step, and is, therefore, threadsafe.
  42.  
  43. '''
  44. from warnings import warn as _warn
  45. from types import MethodType as _MethodType, BuiltinMethodType as _BuiltinMethodType
  46. from math import log as _log, exp as _exp, pi as _pi, e as _e
  47. from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
  48. from os import urandom as _urandom
  49. from binascii import hexlify as _hexlify
  50. __all__ = [
  51.     'Random',
  52.     'seed',
  53.     'random',
  54.     'uniform',
  55.     'randint',
  56.     'choice',
  57.     'sample',
  58.     'randrange',
  59.     'shuffle',
  60.     'normalvariate',
  61.     'lognormvariate',
  62.     'expovariate',
  63.     'vonmisesvariate',
  64.     'gammavariate',
  65.     'gauss',
  66.     'betavariate',
  67.     'paretovariate',
  68.     'weibullvariate',
  69.     'getstate',
  70.     'setstate',
  71.     'jumpahead',
  72.     'WichmannHill',
  73.     'getrandbits',
  74.     'SystemRandom']
  75. NV_MAGICCONST = 4 * _exp(-0.5) / _sqrt(2.0)
  76. TWOPI = 2.0 * _pi
  77. LOG4 = _log(4.0)
  78. SG_MAGICCONST = 1.0 + _log(4.5)
  79. BPF = 53
  80. RECIP_BPF = 2 ** (-BPF)
  81. import _random
  82.  
  83. class Random(_random.Random):
  84.     """Random number generator base class used by bound module functions.
  85.  
  86.     Used to instantiate instances of Random to get generators that don't
  87.     share state.  Especially useful for multi-threaded programs, creating
  88.     a different instance of Random for each thread, and using the jumpahead()
  89.     method to ensure that the generated sequences seen by each thread don't
  90.     overlap.
  91.  
  92.     Class Random can also be subclassed if you want to use a different basic
  93.     generator of your own devising: in that case, override the following
  94.     methods:  random(), seed(), getstate(), setstate() and jumpahead().
  95.     Optionally, implement a getrandombits() method so that randrange()
  96.     can cover arbitrarily large ranges.
  97.  
  98.     """
  99.     VERSION = 2
  100.     
  101.     def __init__(self, x = None):
  102.         '''Initialize an instance.
  103.  
  104.         Optional argument x controls seeding, as for Random.seed().
  105.         '''
  106.         self.seed(x)
  107.         self.gauss_next = None
  108.  
  109.     
  110.     def seed(self, a = None):
  111.         '''Initialize internal state from hashable object.
  112.  
  113.         None or no argument seeds from current time or from an operating
  114.         system specific randomness source if available.
  115.  
  116.         If a is not None or an int or long, hash(a) is used instead.
  117.         '''
  118.         if a is None:
  119.             
  120.             try:
  121.                 a = long(_hexlify(_urandom(16)), 16)
  122.             except NotImplementedError:
  123.                 import time
  124.                 a = long(time.time() * 256)
  125.             except:
  126.                 None<EXCEPTION MATCH>NotImplementedError
  127.             
  128.  
  129.         None<EXCEPTION MATCH>NotImplementedError
  130.         super(Random, self).seed(a)
  131.         self.gauss_next = None
  132.  
  133.     
  134.     def getstate(self):
  135.         '''Return internal state; can be passed to setstate() later.'''
  136.         return (self.VERSION, super(Random, self).getstate(), self.gauss_next)
  137.  
  138.     
  139.     def setstate(self, state):
  140.         '''Restore internal state from object returned by getstate().'''
  141.         version = state[0]
  142.         if version == 2:
  143.             (version, internalstate, self.gauss_next) = state
  144.             super(Random, self).setstate(internalstate)
  145.         else:
  146.             raise ValueError('state with version %s passed to Random.setstate() of version %s' % (version, self.VERSION))
  147.  
  148.     
  149.     def __getstate__(self):
  150.         return self.getstate()
  151.  
  152.     
  153.     def __setstate__(self, state):
  154.         self.setstate(state)
  155.  
  156.     
  157.     def __reduce__(self):
  158.         return (self.__class__, (), self.getstate())
  159.  
  160.     
  161.     def randrange(self, start, stop = None, step = 1, int = int, default = None, maxwidth = 0x1L << BPF):
  162.         """Choose a random item from range(start, stop[, step]).
  163.  
  164.         This fixes the problem with randint() which includes the
  165.         endpoint; in Python this is usually not what you want.
  166.         Do not supply the 'int', 'default', and 'maxwidth' arguments.
  167.         """
  168.         istart = int(start)
  169.         if istart != start:
  170.             raise ValueError, 'non-integer arg 1 for randrange()'
  171.         
  172.         if stop is default:
  173.             if istart > 0:
  174.                 if istart >= maxwidth:
  175.                     return self._randbelow(istart)
  176.                 
  177.                 return int(self.random() * istart)
  178.             
  179.             raise ValueError, 'empty range for randrange()'
  180.         
  181.         istop = int(stop)
  182.         if istop != stop:
  183.             raise ValueError, 'non-integer stop for randrange()'
  184.         
  185.         width = istop - istart
  186.         if step == 1 and width > 0:
  187.             if width >= maxwidth:
  188.                 return int(istart + self._randbelow(width))
  189.             
  190.             return int(istart + int(self.random() * width))
  191.         
  192.         if step == 1:
  193.             raise ValueError, 'empty range for randrange() (%d,%d, %d)' % (istart, istop, width)
  194.         
  195.         istep = int(step)
  196.         if istep != step:
  197.             raise ValueError, 'non-integer step for randrange()'
  198.         
  199.         if istep > 0:
  200.             n = (width + istep - 1) // istep
  201.         elif istep < 0:
  202.             n = (width + istep + 1) // istep
  203.         else:
  204.             raise ValueError, 'zero step for randrange()'
  205.         if n <= 0:
  206.             raise ValueError, 'empty range for randrange()'
  207.         
  208.         if n >= maxwidth:
  209.             return istart + self._randbelow(n)
  210.         
  211.         return istart + istep * int(self.random() * n)
  212.  
  213.     
  214.     def randint(self, a, b):
  215.         '''Return random integer in range [a, b], including both end points.
  216.         '''
  217.         return self.randrange(a, b + 1)
  218.  
  219.     
  220.     def _randbelow(self, n, _log = _log, int = int, _maxwidth = 0x1L << BPF, _Method = _MethodType, _BuiltinMethod = _BuiltinMethodType):
  221.         '''Return a random int in the range [0,n)
  222.  
  223.         Handles the case where n has more bits than returned
  224.         by a single call to the underlying generator.
  225.         '''
  226.         
  227.         try:
  228.             getrandbits = self.getrandbits
  229.         except AttributeError:
  230.             pass
  231.  
  232.         if type(self.random) is _BuiltinMethod or type(getrandbits) is _Method:
  233.             k = int(1.0000100000000001 + _log(n - 1, 2.0))
  234.             r = getrandbits(k)
  235.             while r >= n:
  236.                 r = getrandbits(k)
  237.             return r
  238.         
  239.         if n >= _maxwidth:
  240.             _warn('Underlying random() generator does not supply \nenough bits to choose from a population range this large')
  241.         
  242.         return int(self.random() * n)
  243.  
  244.     
  245.     def choice(self, seq):
  246.         '''Choose a random element from a non-empty sequence.'''
  247.         return seq[int(self.random() * len(seq))]
  248.  
  249.     
  250.     def shuffle(self, x, random = None, int = int):
  251.         '''x, random=random.random -> shuffle list x in place; return None.
  252.  
  253.         Optional arg random is a 0-argument function returning a random
  254.         float in [0.0, 1.0); by default, the standard random.random.
  255.  
  256.         Note that for even rather small len(x), the total number of
  257.         permutations of x is larger than the period of most random number
  258.         generators; this implies that "most" permutations of a long
  259.         sequence can never be generated.
  260.         '''
  261.         if random is None:
  262.             random = self.random
  263.         
  264.         for i in reversed(xrange(1, len(x))):
  265.             j = int(random() * (i + 1))
  266.             x[i] = x[j]
  267.             x[j] = x[i]
  268.         
  269.  
  270.     
  271.     def sample(self, population, k):
  272.         '''Chooses k unique random elements from a population sequence.
  273.  
  274.         Returns a new list containing elements from the population while
  275.         leaving the original population unchanged.  The resulting list is
  276.         in selection order so that all sub-slices will also be valid random
  277.         samples.  This allows raffle winners (the sample) to be partitioned
  278.         into grand prize and second place winners (the subslices).
  279.  
  280.         Members of the population need not be hashable or unique.  If the
  281.         population contains repeats, then each occurrence is a possible
  282.         selection in the sample.
  283.  
  284.         To choose a sample in a range of integers, use xrange as an argument.
  285.         This is especially fast and space efficient for sampling from a
  286.         large population:   sample(xrange(10000000), 60)
  287.         '''
  288.         n = len(population)
  289.         if k <= k:
  290.             pass
  291.         elif not k <= n:
  292.             raise ValueError, 'sample larger than population'
  293.         
  294.         random = self.random
  295.         _int = int
  296.         result = [
  297.             None] * k
  298.         if n < 6 * k:
  299.             pool = list(population)
  300.             for i in xrange(k):
  301.                 j = _int(random() * (n - i))
  302.                 result[i] = pool[j]
  303.                 pool[j] = pool[n - i - 1]
  304.             
  305.         else:
  306.             
  307.             try:
  308.                 if n > 0:
  309.                     pass
  310.                 (population[0], population[n // 2], population[n - 1])
  311.             except (TypeError, KeyError):
  312.                 population = tuple(population)
  313.  
  314.             selected = { }
  315.             for i in xrange(k):
  316.                 j = _int(random() * n)
  317.                 while j in selected:
  318.                     j = _int(random() * n)
  319.                 result[i] = selected[j] = population[j]
  320.             
  321.         return result
  322.  
  323.     
  324.     def uniform(self, a, b):
  325.         '''Get a random number in the range [a, b).'''
  326.         return a + (b - a) * self.random()
  327.  
  328.     
  329.     def normalvariate(self, mu, sigma):
  330.         '''Normal distribution.
  331.  
  332.         mu is the mean, and sigma is the standard deviation.
  333.  
  334.         '''
  335.         random = self.random
  336.         while None:
  337.             u1 = random()
  338.             u2 = 1.0 - random()
  339.             z = NV_MAGICCONST * (u1 - 0.5) / u2
  340.             zz = z * z / 4.0
  341.             if zz <= -_log(u2):
  342.                 break
  343.                 continue
  344.         return mu + z * sigma
  345.  
  346.     
  347.     def lognormvariate(self, mu, sigma):
  348.         """Log normal distribution.
  349.  
  350.         If you take the natural logarithm of this distribution, you'll get a
  351.         normal distribution with mean mu and standard deviation sigma.
  352.         mu can have any value, and sigma must be greater than zero.
  353.  
  354.         """
  355.         return _exp(self.normalvariate(mu, sigma))
  356.  
  357.     
  358.     def expovariate(self, lambd):
  359.         '''Exponential distribution.
  360.  
  361.         lambd is 1.0 divided by the desired mean.  (The parameter would be
  362.         called "lambda", but that is a reserved word in Python.)  Returned
  363.         values range from 0 to positive infinity.
  364.  
  365.         '''
  366.         random = self.random
  367.         u = random()
  368.         while u <= 9.9999999999999995e-008:
  369.             u = random()
  370.         return -_log(u) / lambd
  371.  
  372.     
  373.     def vonmisesvariate(self, mu, kappa):
  374.         '''Circular data distribution.
  375.  
  376.         mu is the mean angle, expressed in radians between 0 and 2*pi, and
  377.         kappa is the concentration parameter, which must be greater than or
  378.         equal to zero.  If kappa is equal to zero, this distribution reduces
  379.         to a uniform random angle over the range 0 to 2*pi.
  380.  
  381.         '''
  382.         random = self.random
  383.         if kappa <= 9.9999999999999995e-007:
  384.             return TWOPI * random()
  385.         
  386.         a = 1.0 + _sqrt(1.0 + 4.0 * kappa * kappa)
  387.         b = (a - _sqrt(2.0 * a)) / (2.0 * kappa)
  388.         r = (1.0 + b * b) / (2.0 * b)
  389.         while None:
  390.             u1 = random()
  391.             z = _cos(_pi * u1)
  392.             f = (1.0 + r * z) / (r + z)
  393.             c = kappa * (r - f)
  394.             u2 = random()
  395.             if u2 < c * (2.0 - c) or u2 <= c * _exp(1.0 - c):
  396.                 break
  397.                 continue
  398.         u3 = random()
  399.         if u3 > 0.5:
  400.             theta = mu % TWOPI + _acos(f)
  401.         else:
  402.             theta = mu % TWOPI - _acos(f)
  403.         return theta
  404.  
  405.     
  406.     def gammavariate(self, alpha, beta):
  407.         '''Gamma distribution.  Not the gamma function!
  408.  
  409.         Conditions on the parameters are alpha > 0 and beta > 0.
  410.  
  411.         '''
  412.         if alpha <= 0.0 or beta <= 0.0:
  413.             raise ValueError, 'gammavariate: alpha and beta must be > 0.0'
  414.         
  415.         random = self.random
  416.         if alpha > 1.0:
  417.             ainv = _sqrt(2.0 * alpha - 1.0)
  418.             bbb = alpha - LOG4
  419.             ccc = alpha + ainv
  420.             while None:
  421.                 u1 = random()
  422.                 if u1 < u1:
  423.                     pass
  424.                 elif not u1 < 0.99999990000000005:
  425.                     continue
  426.                 
  427.                 u2 = 1.0 - random()
  428.                 v = _log(u1 / (1.0 - u1)) / ainv
  429.                 x = alpha * _exp(v)
  430.                 z = u1 * u1 * u2
  431.                 r = bbb + ccc * v - x
  432.                 if r + SG_MAGICCONST - 4.5 * z >= 0.0 or r >= _log(z):
  433.                     return x * beta
  434.                     continue
  435.         elif alpha == 1.0:
  436.             u = random()
  437.             while u <= 9.9999999999999995e-008:
  438.                 u = random()
  439.             return -_log(u) * beta
  440.         else:
  441.             while None:
  442.                 u = random()
  443.                 b = (_e + alpha) / _e
  444.                 p = b * u
  445.                 if p <= 1.0:
  446.                     x = p ** (1.0 / alpha)
  447.                 else:
  448.                     x = -_log((b - p) / alpha)
  449.                 u1 = random()
  450.                 if p > 1.0:
  451.                     if u1 <= x ** (alpha - 1.0):
  452.                         break
  453.                     
  454.                 if u1 <= _exp(-x):
  455.                     break
  456.                     continue
  457.             return x * beta
  458.  
  459.     
  460.     def gauss(self, mu, sigma):
  461.         '''Gaussian distribution.
  462.  
  463.         mu is the mean, and sigma is the standard deviation.  This is
  464.         slightly faster than the normalvariate() function.
  465.  
  466.         Not thread-safe without a lock around calls.
  467.  
  468.         '''
  469.         random = self.random
  470.         z = self.gauss_next
  471.         self.gauss_next = None
  472.         if z is None:
  473.             x2pi = random() * TWOPI
  474.             g2rad = _sqrt(-2.0 * _log(1.0 - random()))
  475.             z = _cos(x2pi) * g2rad
  476.             self.gauss_next = _sin(x2pi) * g2rad
  477.         
  478.         return mu + z * sigma
  479.  
  480.     
  481.     def betavariate(self, alpha, beta):
  482.         '''Beta distribution.
  483.  
  484.         Conditions on the parameters are alpha > -1 and beta} > -1.
  485.         Returned values range between 0 and 1.
  486.  
  487.         '''
  488.         y = self.gammavariate(alpha, 1.0)
  489.         if y == 0:
  490.             return 0.0
  491.         else:
  492.             return y / (y + self.gammavariate(beta, 1.0))
  493.  
  494.     
  495.     def paretovariate(self, alpha):
  496.         '''Pareto distribution.  alpha is the shape parameter.'''
  497.         u = 1.0 - self.random()
  498.         return 1.0 / pow(u, 1.0 / alpha)
  499.  
  500.     
  501.     def weibullvariate(self, alpha, beta):
  502.         '''Weibull distribution.
  503.  
  504.         alpha is the scale parameter and beta is the shape parameter.
  505.  
  506.         '''
  507.         u = 1.0 - self.random()
  508.         return alpha * pow(-_log(u), 1.0 / beta)
  509.  
  510.  
  511.  
  512. class WichmannHill(Random):
  513.     VERSION = 1
  514.     
  515.     def seed(self, a = None):
  516.         '''Initialize internal state from hashable object.
  517.  
  518.         None or no argument seeds from current time or from an operating
  519.         system specific randomness source if available.
  520.  
  521.         If a is not None or an int or long, hash(a) is used instead.
  522.  
  523.         If a is an int or long, a is used directly.  Distinct values between
  524.         0 and 27814431486575L inclusive are guaranteed to yield distinct
  525.         internal states (this guarantee is specific to the default
  526.         Wichmann-Hill generator).
  527.         '''
  528.         if a is None:
  529.             
  530.             try:
  531.                 a = long(_hexlify(_urandom(16)), 16)
  532.             except NotImplementedError:
  533.                 import time
  534.                 a = long(time.time() * 256)
  535.             except:
  536.                 None<EXCEPTION MATCH>NotImplementedError
  537.             
  538.  
  539.         None<EXCEPTION MATCH>NotImplementedError
  540.         if not isinstance(a, (int, long)):
  541.             a = hash(a)
  542.         
  543.         (a, x) = divmod(a, 30268)
  544.         (a, y) = divmod(a, 30306)
  545.         (a, z) = divmod(a, 30322)
  546.         self._seed = (int(x) + 1, int(y) + 1, int(z) + 1)
  547.         self.gauss_next = None
  548.  
  549.     
  550.     def random(self):
  551.         '''Get the next random number in the range [0.0, 1.0).'''
  552.         (x, y, z) = self._seed
  553.         x = 171 * x % 30269
  554.         y = 172 * y % 30307
  555.         z = 170 * z % 30323
  556.         self._seed = (x, y, z)
  557.         return (x / 30269.0 + y / 30307.0 + z / 30323.0) % 1.0
  558.  
  559.     
  560.     def getstate(self):
  561.         '''Return internal state; can be passed to setstate() later.'''
  562.         return (self.VERSION, self._seed, self.gauss_next)
  563.  
  564.     
  565.     def setstate(self, state):
  566.         '''Restore internal state from object returned by getstate().'''
  567.         version = state[0]
  568.         if version == 1:
  569.             (version, self._seed, self.gauss_next) = state
  570.         else:
  571.             raise ValueError('state with version %s passed to Random.setstate() of version %s' % (version, self.VERSION))
  572.  
  573.     
  574.     def jumpahead(self, n):
  575.         '''Act as if n calls to random() were made, but quickly.
  576.  
  577.         n is an int, greater than or equal to 0.
  578.  
  579.         Example use:  If you have 2 threads and know that each will
  580.         consume no more than a million random numbers, create two Random
  581.         objects r1 and r2, then do
  582.             r2.setstate(r1.getstate())
  583.             r2.jumpahead(1000000)
  584.         Then r1 and r2 will use guaranteed-disjoint segments of the full
  585.         period.
  586.         '''
  587.         if not n >= 0:
  588.             raise ValueError('n must be >= 0')
  589.         
  590.         (x, y, z) = self._seed
  591.         x = int(x * pow(171, n, 30269)) % 30269
  592.         y = int(y * pow(172, n, 30307)) % 30307
  593.         z = int(z * pow(170, n, 30323)) % 30323
  594.         self._seed = (x, y, z)
  595.  
  596.     
  597.     def __whseed(self, x = 0, y = 0, z = 0):
  598.         '''Set the Wichmann-Hill seed from (x, y, z).
  599.  
  600.         These must be integers in the range [0, 256).
  601.         '''
  602.         if type(y) == type(y) and type(z) == type(z):
  603.             pass
  604.         elif not type(z) == int:
  605.             raise TypeError('seeds must be integers')
  606.         
  607.         if x <= x:
  608.             pass
  609.         elif x < 256:
  610.             if y <= y:
  611.                 pass
  612.             elif y < 256:
  613.                 if z <= z:
  614.                     pass
  615.                 elif not z < 256:
  616.                     raise ValueError('seeds must be in range(0, 256)')
  617.                 
  618.         if x == x and y == y:
  619.             pass
  620.         elif y == z:
  621.             import time
  622.             t = long(time.time() * 256)
  623.             t = int(t & 16777215 ^ t >> 24)
  624.             (t, x) = divmod(t, 256)
  625.             (t, y) = divmod(t, 256)
  626.             (t, z) = divmod(t, 256)
  627.         
  628.         if not x:
  629.             pass
  630.         if not y:
  631.             pass
  632.         if not z:
  633.             pass
  634.         self._seed = (1, 1, 1)
  635.         self.gauss_next = None
  636.  
  637.     
  638.     def whseed(self, a = None):
  639.         """Seed from hashable object's hash code.
  640.  
  641.         None or no argument seeds from current time.  It is not guaranteed
  642.         that objects with distinct hash codes lead to distinct internal
  643.         states.
  644.  
  645.         This is obsolete, provided for compatibility with the seed routine
  646.         used prior to Python 2.1.  Use the .seed() method instead.
  647.         """
  648.         if a is None:
  649.             self._WichmannHill__whseed()
  650.             return None
  651.         
  652.         a = hash(a)
  653.         (a, x) = divmod(a, 256)
  654.         (a, y) = divmod(a, 256)
  655.         (a, z) = divmod(a, 256)
  656.         if not (x + a) % 256:
  657.             pass
  658.         x = 1
  659.         if not (y + a) % 256:
  660.             pass
  661.         y = 1
  662.         if not (z + a) % 256:
  663.             pass
  664.         z = 1
  665.         self._WichmannHill__whseed(x, y, z)
  666.  
  667.  
  668.  
  669. class SystemRandom(Random):
  670.     '''Alternate random number generator using sources provided
  671.     by the operating system (such as /dev/urandom on Unix or
  672.     CryptGenRandom on Windows).
  673.  
  674.      Not available on all systems (see os.urandom() for details).
  675.     '''
  676.     
  677.     def random(self):
  678.         '''Get the next random number in the range [0.0, 1.0).'''
  679.         return (long(_hexlify(_urandom(7)), 16) >> 3) * RECIP_BPF
  680.  
  681.     
  682.     def getrandbits(self, k):
  683.         '''getrandbits(k) -> x.  Generates a long int with k random bits.'''
  684.         if k <= 0:
  685.             raise ValueError('number of bits must be greater than zero')
  686.         
  687.         if k != int(k):
  688.             raise TypeError('number of bits should be an integer')
  689.         
  690.         bytes = (k + 7) // 8
  691.         x = long(_hexlify(_urandom(bytes)), 16)
  692.         return x >> bytes * 8 - k
  693.  
  694.     
  695.     def _stub(self, *args, **kwds):
  696.         '''Stub method.  Not used for a system random number generator.'''
  697.         pass
  698.  
  699.     seed = jumpahead = _stub
  700.     
  701.     def _notimplemented(self, *args, **kwds):
  702.         '''Method should not be called for a system random number generator.'''
  703.         raise NotImplementedError('System entropy source does not have state.')
  704.  
  705.     getstate = setstate = _notimplemented
  706.  
  707.  
  708. def _test_generator(n, func, args):
  709.     import time
  710.     print n, 'times', func.__name__
  711.     total = 0.0
  712.     sqsum = 0.0
  713.     smallest = 10000000000.0
  714.     largest = -10000000000.0
  715.     t0 = time.time()
  716.     for i in range(n):
  717.         x = func(*args)
  718.         total += x
  719.         sqsum = sqsum + x * x
  720.         smallest = min(x, smallest)
  721.         largest = max(x, largest)
  722.     
  723.     t1 = time.time()
  724.     print round(t1 - t0, 3), 'sec,',
  725.     avg = total / n
  726.     stddev = _sqrt(sqsum / n - avg * avg)
  727.     print 'avg %g, stddev %g, min %g, max %g' % (avg, stddev, smallest, largest)
  728.  
  729.  
  730. def _test(N = 2000):
  731.     _test_generator(N, random, ())
  732.     _test_generator(N, normalvariate, (0.0, 1.0))
  733.     _test_generator(N, lognormvariate, (0.0, 1.0))
  734.     _test_generator(N, vonmisesvariate, (0.0, 1.0))
  735.     _test_generator(N, gammavariate, (0.01, 1.0))
  736.     _test_generator(N, gammavariate, (0.10000000000000001, 1.0))
  737.     _test_generator(N, gammavariate, (0.10000000000000001, 2.0))
  738.     _test_generator(N, gammavariate, (0.5, 1.0))
  739.     _test_generator(N, gammavariate, (0.90000000000000002, 1.0))
  740.     _test_generator(N, gammavariate, (1.0, 1.0))
  741.     _test_generator(N, gammavariate, (2.0, 1.0))
  742.     _test_generator(N, gammavariate, (20.0, 1.0))
  743.     _test_generator(N, gammavariate, (200.0, 1.0))
  744.     _test_generator(N, gauss, (0.0, 1.0))
  745.     _test_generator(N, betavariate, (3.0, 3.0))
  746.  
  747. _inst = Random()
  748. seed = _inst.seed
  749. random = _inst.random
  750. uniform = _inst.uniform
  751. randint = _inst.randint
  752. choice = _inst.choice
  753. randrange = _inst.randrange
  754. sample = _inst.sample
  755. shuffle = _inst.shuffle
  756. normalvariate = _inst.normalvariate
  757. lognormvariate = _inst.lognormvariate
  758. expovariate = _inst.expovariate
  759. vonmisesvariate = _inst.vonmisesvariate
  760. gammavariate = _inst.gammavariate
  761. gauss = _inst.gauss
  762. betavariate = _inst.betavariate
  763. paretovariate = _inst.paretovariate
  764. weibullvariate = _inst.weibullvariate
  765. getstate = _inst.getstate
  766. setstate = _inst.setstate
  767. jumpahead = _inst.jumpahead
  768. getrandbits = _inst.getrandbits
  769. if __name__ == '__main__':
  770.     _test()
  771.  
  772.